#pragma once

enum VertexFMT
{
	VERTEX3F		= D3DFVF_XYZ,
	VERTEX3FRHW		= D3DFVF_XYZRHW,
	VERTEX3FRHWT	= D3DFVF_XYZRHW | D3DFVF_TEX1,
	VERTEX3FRHWC	= D3DFVF_XYZRHW | D3DFVF_DIFFUSE,
	VERTEX3FCRHWT	= D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1,
	VERTEX3FC		= D3DFVF_XYZ | D3DFVF_DIFFUSE,
	VERTEX3FT		= D3DFVF_XYZ | D3DFVF_TEX1,
	VERTEX3FCT		= D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1,
	VERTEX3FT2		= D3DFVF_XYZ | D3DFVF_TEX2,
	VERTEX3FNT2		= D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX2,
};

#pragma pack(1)

#define M_PI	3.141592f

struct Vertex3F
{
	Vertex3F(float x, float y, float z) : x(x), y(y), z(z)
	{
	}

	Vertex3F() : x(0), y(0), z(0)
	{
	}

	Vertex3F(float* arr) : x(arr[0]), y(arr[1]), z(arr[2]) {
	}

	Vertex3F operator - (const Vertex3F& other) {
		return Vertex3F(x - other.x, y - other.y, z - other.z);
	}

	float Length()
	{
		return sqrtf(powf(x, 2) + powf(y, 2) + powf(z, 2));
	}

	operator float*()
	{
		return (float*)this;
	}

	operator D3DXVECTOR3() { return D3DXVECTOR3(x, y, z); }

	operator D3DXVECTOR3*() { return (D3DXVECTOR3*)this; }

	float x, y, z;
};

struct Vertex3FRHW
{
	float x, y, z;
	float rhw;
};

struct Vertex3FRHWC
{
	float x, y, z;
	float rhw;
	DWORD dwColor;
};

struct Vertex3FRHWT
{
	float x, y, z;
	float rhw;
	float u, v;
	Vertex3FRHWT()
	{
		rhw = 1.0f;
		z = 0.0f;
	}

	static const int FVF = D3DFVF_XYZRHW | D3DFVF_TEX1;
};

struct _Vertex3FRHWT
{
	float x, y, z;
	float rhw;
	float u, v;
};

struct Vertex3FCRHW
{
	float x, y, z;
	float rhw;
	DWORD color;

	static const int FVF = D3DFVF_XYZRHW | D3DFVF_DIFFUSE;
};

struct Vertex3FRHWTU
{
	float x, y, z;
	float rhw;
	float u, v;
};

struct Vertex3FT
{
	float x, y, z;
	float u, v;
};

struct Vertex3FT2
{
	float x, y, z;
	float u, v, s, t;
};

struct Vertex3FNT2
{
	float x, y, z;
	float nx, ny, nz;
	float u, v, s, t;
};

struct Vertex3FCNT2
{
	float x, y, z;
	float nx, ny, nz;
	DWORD dwColor;
	float u, v, s, t;

	static const DWORD FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL | D3DFVF_TEX2;
	static const DWORD stride = 44;
};

struct Vertex3FC
{
	float x, y, z;
	DWORD color;
};

struct Vertex3FCRHWT
{
	float x, y, z;
	float rhw;
	DWORD dwcolor;
	float u, v;
};

struct Vertex2F
{
	Vertex2F(float x, float y) : x(x), y(y)
	{
	}
	Vertex2F()
	{
	}
	float x, y;
};

#pragma pack()